home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / hack / 1 / src / termcap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1985-07-26  |  5.4 KB  |  277 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2. /* hack.termcap.c - version 1.0.3 */
  3.  
  4. #include <stdio.h>
  5. #include "config.h"    /* for ROWNO and COLNO */
  6. #include "def.flag.h"    /* for flags.nonull */
  7. extern char *tgetstr(), *tgoto(), *getenv();
  8. extern long *alloc();
  9.  
  10. #ifndef lint
  11. extern            /* it is defined in libtermlib (libtermcap) */
  12. #endif lint
  13.     short ospeed;        /* terminal baudrate; used by tputs */
  14. static char tbuf[512];
  15. static char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE;
  16. static char *VS, *VE;
  17. static int SG;
  18. static char PC = '\0';
  19. char *CD;        /* tested in pri.c: docorner() */
  20. int CO, LI;        /* used in pri.c and whatis.c */
  21.  
  22. startup()
  23. {
  24.     register char *term;
  25.     register char *tptr;
  26.     char *tbufptr, *pc;
  27.  
  28.     tptr = (char *) alloc(1024);
  29.  
  30.     tbufptr = tbuf;
  31.     if(!(term = getenv("TERM")))
  32.         error("Can't get TERM.");
  33.     if(!strncmp(term, "5620", 4))
  34.         flags.nonull = 1;    /* this should be a termcap flag */
  35.     if(tgetent(tptr, term) < 1)
  36.         error("Unknown terminal type: %s.", term);
  37.     if(pc = tgetstr("pc", &tbufptr))
  38.         PC = *pc;
  39.     if(!(BC = tgetstr("bc", &tbufptr))) {    
  40.         if(!tgetflag("bs"))
  41.             error("Terminal must backspace.");
  42.         BC = tbufptr;
  43.         tbufptr += 2;
  44.         *BC = '\b';
  45.     }
  46.     HO = tgetstr("ho", &tbufptr);
  47.     CO = tgetnum("co");
  48.     LI = tgetnum("li");
  49.     if(CO < COLNO || LI < ROWNO+2)
  50.         setclipped();
  51.     if(!(CL = tgetstr("cl", &tbufptr)))
  52.         error("Hack needs CL.");
  53.     ND = tgetstr("nd", &tbufptr);
  54.     if(tgetflag("os"))
  55.         error("Hack can't have OS.");
  56.     CE = tgetstr("ce", &tbufptr);
  57.     UP = tgetstr("up", &tbufptr);
  58.     /* It seems that xd is no longer supported, and we should use
  59.        a linefeed instead; unfortunately this requires resetting
  60.        CRMOD, and many output routines will have to be modified
  61.        slightly. Let's leave that till the next release. */
  62.     XD = tgetstr("xd", &tbufptr);
  63. /* not:         XD = tgetstr("do", &tbufptr); */
  64.     if(!(CM = tgetstr("cm", &tbufptr))) {
  65.         if(!UP && !HO)
  66.             error("Hack needs CM or UP or HO.");
  67.         printf("Playing hack on terminals without cm is suspect...\n");
  68.         getret();
  69.     }
  70.     SO = tgetstr("so", &tbufptr);
  71.     SE = tgetstr("se", &tbufptr);
  72.     SG = tgetnum("sg");    /* -1: not fnd; else # of spaces left by so */
  73.     if(!SO || !SE || (SG > 0)) SO = SE = 0;
  74.     CD = tgetstr("cd", &tbufptr);
  75.     set_whole_screen();        /* uses LI and CD */
  76.     if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n");
  77.     free(tptr);
  78. }
  79.  
  80. start_screen()
  81. {
  82.     xputs(TI);
  83.     xputs(VS);
  84. }
  85.  
  86. end_screen()
  87. {
  88.     xputs(VE);
  89.     xputs(TE);
  90. }
  91.  
  92. /* Cursor movements */
  93. extern xchar curx, cury;
  94.  
  95. curs(x, y)
  96. register int x, y;    /* not xchar: perhaps xchar is unsigned and
  97.                curx-x would be unsigned as well */
  98. {
  99.  
  100.     if (y == cury && x == curx)
  101.         return;
  102.     if(!ND && (curx != x || x <= 3)) {    /* Extremely primitive */
  103.         cmov(x, y);            /* bunker!wtm */
  104.         return;
  105.     }
  106.     if(abs(cury-y) <= 3 && abs(curx-x) <= 3)
  107.         nocmov(x, y);
  108.     else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) {
  109.         (void) putchar('\r');
  110.         curx = 1;
  111.         nocmov(x, y);
  112.     } else if(!CM) {
  113.         nocmov(x, y);
  114.     } else
  115.         cmov(x, y);
  116. }
  117.  
  118. nocmov(x, y)
  119. {
  120.     if (cury > y) {
  121.         if(UP) {
  122.             while (cury > y) {    /* Go up. */
  123.                 xputs(UP);
  124.                 cury--;
  125.             }
  126.         } else if(CM) {
  127.             cmov(x, y);
  128.         } else if(HO) {
  129.             home();
  130.             curs(x, y);
  131.         } /* else impossible("..."); */
  132.     } else if (cury < y) {
  133.         if(XD) {
  134.             while(cury < y) {
  135.                 xputs(XD);
  136.                 cury++;
  137.             }
  138.         } else if(CM) {
  139.             cmov(x, y);
  140.         } else {
  141.             while(cury < y) {
  142.                 xputc('\n');
  143.                 curx = 1;
  144.                 cury++;
  145.             }
  146.         }
  147.     }
  148.     if (curx < x) {        /* Go to the right. */
  149.         if(!ND) cmov(x, y); else    /* bah */
  150.             /* should instead print what is there already */
  151.         while (curx < x) {
  152.             xputs(ND);
  153.             curx++;
  154.         }
  155.     } else if (curx > x) {
  156.         while (curx > x) {    /* Go to the left. */
  157.             xputs(BC);
  158.             curx--;
  159.         }
  160.     }
  161. }
  162.  
  163. cmov(x, y)
  164. register x, y;
  165. {
  166.     xputs(tgoto(CM, x-1, y-1));
  167.     cury = y;
  168.     curx = x;
  169. }
  170.  
  171. xputc(c) char c; {
  172.     (void) fputc(c, stdout);
  173. }
  174.  
  175. xputs(s) char *s; {
  176.     tputs(s, 1, xputc);
  177. }
  178.  
  179. cl_end() {
  180.     if(CE)
  181.         xputs(CE);
  182.     else {    /* no-CE fix - free after Harold Rynes */
  183.         /* this looks terrible, especially on a slow terminal
  184.            but is better than nothing */
  185.         register cx = curx, cy = cury;
  186.  
  187.         while(curx < COLNO) {
  188.             xputc(' ');
  189.             curx++;
  190.         }
  191.         curs(cx, cy);
  192.     }
  193. }
  194.  
  195. clear_screen() {
  196.     xputs(CL);
  197.     curx = cury = 1;
  198. }
  199.  
  200. home()
  201. {
  202.     if(HO)
  203.         xputs(HO);
  204.     else if(CM)
  205.         xputs(tgoto(CM, 0, 0));
  206.     else
  207.         curs(1, 1);    /* using UP ... */
  208.     curx = cury = 1;
  209. }
  210.  
  211. standoutbeg()
  212. {
  213.     if(SO) xputs(SO);
  214. }
  215.  
  216. standoutend()
  217. {
  218.     if(SE) xputs(SE);
  219. }
  220.  
  221. backsp()
  222. {
  223.     xputs(BC);
  224.     curx--;
  225. }
  226.  
  227. bell()
  228. {
  229.     (void) putchar('\007');        /* curx does not change */
  230.     (void) fflush(stdout);
  231. }
  232.  
  233. static short tmspc10[] = {        /* from termcap */
  234.     0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5
  235. };
  236.  
  237. delay_output() {
  238.     /* delay 50 ms - could also use a 'nap'-system call */
  239.     /* BUG: if the padding character is visible, as it is on the 5620
  240.        then this looks terrible. */
  241.     if(!flags.nonull)
  242.         tputs("50", 1, xputc);
  243.  
  244.         /* cbosgd!cbcephus!pds for SYS V R2 */
  245.         /* is this terminfo, or what? */
  246.         /* tputs("$<50>", 1, xputc); */
  247.  
  248.     else if(ospeed > 0 || ospeed < SIZE(tmspc10)) if(CM) {
  249.         /* delay by sending cm(here) an appropriate number of times */
  250.         register int cmlen = strlen(tgoto(CM, curx-1, cury-1));
  251.         register int i = 500 + tmspc10[ospeed]/2;
  252.  
  253.         while(i > 0) {
  254.             cmov(curx, cury);
  255.             i -= cmlen*tmspc10[ospeed];
  256.         }
  257.     }
  258. }
  259.  
  260. cl_eos()            /* free after Robert Viduya */
  261. {                /* must only be called with curx = 1 */
  262.  
  263.     if(CD)
  264.         xputs(CD);
  265.     else {
  266.         register int cx = curx, cy = cury;
  267.         while(cury <= LI-2) {
  268.             cl_end();
  269.             xputc('\n');
  270.             curx = 1;
  271.             cury++;
  272.         }
  273.         cl_end();
  274.         curs(cx, cy);
  275.     }
  276. }
  277.